package com.heima.leetcode.practice;

import java.util.Arrays;
import java.util.StringJoiner;

/**
 * @author 勾新杰
 * @version 1.0
 * @description: leetcode 557. 反转字符串中的单词 III
 * @date 2024/10/25 8:03
 */
public class E557 {

    /**
     * <h3>方法一：反转的时候用两个数组</h3>
     *
     * @param s 待处理字符串
     * @return 反转后的字符串
     */
    public String reverseWords1(String s) {
        String[] split = s.split(" ");
        String[] result = new String[split.length];
        for (int i = 0; i < split.length; i++) {
            char[] charArray = split[i].toCharArray();
            int length = charArray.length;
            char[] replace = new char[length];
            int index = 0;
            for (int j = length - 1; j >= 0; j--) {
                replace[index++] = charArray[j];
            }
            System.arraycopy(replace, 0, charArray, 0, length);
            result[i] = String.valueOf(charArray);
        }
        return String.join(" ", result);
    }

    /**
     * <h3>方法二：反转的时候用一个数组</h3>
     *
     * @param s 待处理字符串
     * @return 反转后的字符串
     */
    public String reverseWords2(String s) {
        String[] split = s.split(" ");
        String[] result = new String[split.length];
        for (int i = 0; i < split.length; i++) {
            char[] charArray = split[i].toCharArray();
            // 0 1 2 3 4 5
            int length = charArray.length;
            for (int j = 0; j < length >> 1; j++) {
                char temp = charArray[j];
                charArray[j] = charArray[length - j - 1];
                charArray[length - j - 1] = temp;
            }
            result[i] = String.valueOf(charArray);
        }
        return String.join(" ", result);
    }

    /**
     * <h3>方法三：反转字符串时用StringBuilder</h3>
     *
     * @param s 待处理字符串
     * @return 反转后的字符
     */
    public String reverseWords3(String s) {
        String[] split = s.split(" ");
        String[] result = new String[split.length];
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < split.length; i++) {
            char[] charArray = split[i].toCharArray();
            for (int j = charArray.length - 1; j >= 0; j--) {
                builder.append(charArray[j]);
            }
            result[i] = builder.toString();
            builder.setLength(0);
        }
        // StringJoiner joiner = new StringJoiner(" ");
        // for (String string : result) {
        //     joiner.add(string);
        // }
        // return joiner.toString();
        return String.join(" ", result);
    }

    /**
     * <h3>方法四：在原整个字符串进行反转</h3>
     *
     * @param s 待处理字符串
     * @return 反转后的字符
     */
    public String reverseWords4(String s) {
        char[] result = s.toCharArray();
        int begin = 0;
        int end;
        for (int i = 0; i < result.length; i++) {
            // 一次处理一个空格之前的一个单词
            if (result[i] == ' ') {
                end = i - 1;
                reverse(result, begin, end);
                begin = i + 1;
            }
            // 处理最后一个单词
            if (i == result.length - 1) {
                reverse(result, begin, i);
            }
            // 上述两个if可以合并
        }
        return String.valueOf(result);
    }

    /**
     * 反转指定范围的字符数组
     *
     * @param array 字符数组
     * @param begin 开始索引（包含）
     * @param end   结束索引（包含）
     */
    private void reverse(char[] array, int begin, int end) {
        while (begin < end) {
            char temp = array[begin];
            array[begin++] = array[end];
            array[end--] = temp;
        }
    }

    /**
     * <h3>方法五：使用StringJoiner和反转</h3>
     *
     * @param s 待处理字符串
     * @return 反转后的字符
     */
    public String reverseWords5(String s) {
        String[] split = s.split(" ");
        StringJoiner joiner = new StringJoiner(" ");
        for (String str : split) {
            char[] charArray = str.toCharArray();
            reverseString(charArray);
            joiner.add(new String(charArray));
        }
        return joiner.toString();
    }

    /**
     * <h3>方法一：双指针</h3>
     *
     * @param s 字符数组
     */
    private void reverseString(char[] s) {
        int left = 0, right = s.length - 1;
        while (left < right)
            swap(s, left++, right--);
    }

    /**
     * 交换字符数组中两个位置的值
     *
     * @param s     字符数组
     * @param left  左指针
     * @param right 右指针
     */
    public void swap(char[] s, int left, int right) {
        char temp = s[left];
        s[left] = s[right];
        s[right] = temp;
    }
}
